# gozerbot/utils/locking.py
#
#

""" generic functions """

__copyright__ = 'this file is in the public domain'

from log import rlog, loglevel
from trace import whichmodule
from lockmanager import lockmanager, rlockmanager

import logging, sys
locks = []

def lockdec(lock):

    """ locking decorator. """

    def locked(func):

        """ locking function for %s """ % str(func)

        def lockedfunc(*args, **kwargs):
            """ the locked function. """

            if loglevel <= 1:
                where = whichmodule(1)
                rlog(1, 'locking', 'locking on %s (%s)' % (where, str(func)))
            lock.acquire()
            locks.append(str(func))
            res = None

            try:
                res = func(*args, **kwargs)
            finally:
                lock.release()
                locks.remove(str(func))

            return res

        return lockedfunc

    return locked

def funclocked(func):

    """ locking function for %s """ % str(func)

    def lockedfunc(*args, **kwargs):

        """ the locked function. """

        if loglevel <= 1:
            where = whichmodule(1)
            rlog(1, 'locking', 'locking on %s' % where)
        rlockmanager.acquire(func)
        locks.append(str(func))
        res = None

        try:
            res = func(*args, **kwargs)
        finally:
            rlockmanager.release(func)
            locks.remove(str(func))

        return res


    return lockedfunc

class Locked(object):

    """ class used to lock an entire object. """

    def __getattribute__(self, attr):
        if loglevel <= 1:
            where = whichmodule(1)
            rlog(1, 'locking', 'locking on %s' % where)
        rlockmanager.acquire(object)
        res = None

        try:
            res = super(Locked, self).__getattribute__(attr)
        finally:
            rlockmanager.release(object)

        return res
